/**
 * float4_tests.js
 * 
 * Test Float4 functionality.
 * 
 * @author A.Weissflog
 * 
 * (C) 2010 A.Weissflog
 */

Float4.TestDefaultConstructor = function()
{
	var f = new Float4();
	return ((f.x == 0.0) && (f.y == 0.0) && (f.z == 0.0) && (f.w == 0.0));
}

Float4.TestFromValues = function()
{
	var f = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	return ((f.x == 1.0) && (f.y == 2.0) && (f.z == 3.0) && (f.w == 4.0));
}

Float4.TestFromFloat4 = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromFloat4(f0);
	f0.Set(2.0, 3.0, 4.0, 5.0);
	return (f1.x == 1.0) && (f1.y == 2.0) && (f1.z == 3.0) && (f1.w == 4.0) &&
           (f0.x == 2.0) && (f0.y == 3.0) && (f0.z == 4.0) && (f0.w == 5.0);
}

Float4.TestSet = function()
{
	var f = new Float4;
	f.Set(1.0, 2.0, 3.0, 4.0);
	return ((f.x == 1.0) && (f.y == 2.0) && (f.z == 3.0) && (f.w == 4.0));	
}

Float4.TestInplaceAdd = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	f0.Add(f1);
	return (f0.x == 2.0) && (f0.y == 4.0) && (f0.z == 6.0) && (f0.w == 8.0) &&
		   (f1.x == 1.0) && (f1.y == 2.0) && (f1.z == 3.0) && (f1.w == 4.0)
}

Float4.TestAdd = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f2 = Float4.Add(f0, f1);
	return (f2.x == 2.0) && (f2.y == 4.0) && (f2.z == 6.0) && (f2.w == 8.0) &&
		   (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0) &&
		   (f1.x == 1.0) && (f1.y == 2.0) && (f1.z == 3.0) && (f1.w == 4.0);
}

Float4.TestInplaceSub = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f1 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	f0.Sub(f1);
	return (f0.x == 1.0) && (f0.y == 1.0) && (f0.z == 1.0) && (f0.w == 1.0) &&
		   (f1.x == 1.0) && (f1.y == 2.0) && (f1.z == 3.0) && (f1.w == 4.0);
}

Float4.TestSub = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f1 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f2 = Float4.Sub(f0, f1);
	
	return (f2.x == 1.0) && (f2.y == 1.0) && (f2.z == 1.0) && (f2.w == 1.0) &&
		   (f0.x == 2.0) && (f0.y == 3.0) && (f0.z == 4.0) && (f0.w == 5.0) &&
		   (f1.x == 1.0) && (f1.y == 2.0) && (f1.z == 3.0) && (f1.w == 4.0);
}

Float4.TestDot3 = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var dot = Float4.Dot3(f0, f1);
	return (dot == 20.0) &&
		   (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0) &&
		   (f1.x == 2.0) && (f1.y == 3.0) && (f1.z == 4.0) && (f1.w == 5.0);
}

Float4.TestLength = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 2.0, 0.0);
	return (f0.Length() == 3.0) &&
		   (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 2.0) && (f0.w == 0.0);
}

Float4.TestLengthSquared = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	return (f0.LengthSq() == 30.0) &&
	       (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0); 
}

Float4.TestReciprocal = function()
{
	var f0 = Float4.FromValues(2.0, 4.0, 5.0, 8.0);
	f0.Reciprocal();
	return (f0.x == 0.5) && (f0.y == 0.25) && (f0.z == 0.2) && (f0.w == 0.125);
}

Float4.TestInplaceMul = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f1 = Float4.FromValues(3.0, 4.0, 5.0, 6.0);
	f0.Mul(f1);
	return (f0.x == 6.0) && (f0.y == 12.0) && (f0.z == 20.0) && (f0.w == 30.0) &&
		   (f1.x == 3.0) && (f1.y == 4.0) && (f1.z == 5.0) && (f1.w == 6.0);
}

Float4.TestMul = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f1 = Float4.FromValues(3.0, 4.0, 5.0, 6.0);
	var f2 = Float4.Mul(f0, f1);
	return (f2.x == 6.0) && (f2.y == 12.0) && (f2.z == 20.0) && (f2.w == 30.0) &&
		   (f0.x == 2.0) && (f0.y == 3.0) && (f0.z == 4.0) && (f0.w == 5.0) &&
		   (f1.x == 3.0) && (f1.y == 4.0) && (f1.z == 5.0) && (f1.w == 6.0);		
}

Float4.TestAbs = function()
{
	var f0 = Float4.FromValues(-1.0, -2.0, -3.0, -4.0);
	f0.Abs();
	return (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0);
}

Float4.TestInplaceCross3 = function()
{
	var f0 = Float4.FromValues(1.0, 0.0, 0.0, 0.0);
	var f1 = Float4.FromValues(0.0, 0.0, 1.0, 0.0);
	f0.Cross3(f1);
	return (f0.x == 0.0) && (f0.y == -1.0) && (f0.z == 0.0) && (f0.w == 0.0) &&
		   (f1.x == 0.0) && (f1.y == 0.0) && (f1.z == 1.0) && (f1.w == 0.0);
}

Float4.TestCross3 = function()
{
	var f0 = Float4.FromValues(1.0, 0.0, 0.0, 0.0);
	var f1 = Float4.FromValues(0.0, 0.0, 1.0, 0.0);
	var f2 = Float4.Cross3(f0, f1);
	return (f2.x == 0.0) && (f2.y == -1.0) && (f2.z == 0.0) && (f2.w == 0.0) &&
	       (f0.x == 1.0) && (f0.y == 0.0) && (f0.z == 0.0) && (f0.w == 0.0) &&
		   (f1.x == 0.0) && (f1.y == 0.0) && (f1.z == 1.0) && (f1.w == 0.0);
}

Float4.TestInplaceLerp = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	f0.Lerp(f1, 0.25);
	return (f0.x == 1.25) && (f0.y == 2.25) && (f0.z == 3.25) && (f0.w == 4.25) &&
	       (f1.x == 2.0) && (f1.y == 3.0) && (f1.z == 4.0) && (f1.w == 5.0);
}

Float4.TestLerp = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f2 = Float4.Lerp(f0, f1, 0.25);
	return (f2.x == 1.25) && (f2.y == 2.25) && (f2.z == 3.25) && (f2.w == 4.25) &&
	       (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0) &&
		   (f1.x == 2.0) && (f1.y == 3.0) && (f1.z == 4.0) && (f1.w == 5.0);
}

Float4.TestInplaceMax = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(0.5, 2.5, 1.5, 4.1);
	f0.Max(f1);
	return (f0.x == 1.0) && (f0.y == 2.5) && (f0.z == 3.0) && (f0.w == 4.1) &&
	       (f1.x == 0.5) && (f1.y == 2.5) && (f1.z == 1.5) && (f1.w == 4.1);
}

Float4.TestMax = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(0.5, 2.5, 1.5, 4.1);
	var f2 = Float4.Max(f0, f1);
	return (f2.x == 1.0) && (f2.y == 2.5) && (f2.z == 3.0) && (f2.w == 4.1) &&
	       (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0) &&
		   (f1.x == 0.5) && (f1.y == 2.5) && (f1.z == 1.5) && (f1.w == 4.1);
}

Float4.TestInplaceMin = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(0.5, 2.5, 1.5, 4.1);
	f0.Min(f1);
	return (f0.x == 0.5) && (f0.y == 2.0) && (f0.z == 1.5) && (f0.w == 4.0) &&
		   (f1.x == 0.5) && (f1.y == 2.5) && (f1.z == 1.5) && (f1.w == 4.1);
}

Float4.TestMin = function()
{
	var f0 = Float4.FromValues(1.0, 2.0, 3.0, 4.0);
	var f1 = Float4.FromValues(0.5, 2.5, 1.5, 4.1);
	var f2 = Float4.Min(f0, f1);
	return (f2.x == 0.5) && (f2.y == 2.0) && (f2.z == 1.5) && (f2.w == 4.0) &&
		   (f0.x == 1.0) && (f0.y == 2.0) && (f0.z == 3.0) && (f0.w == 4.0) &&
		   (f1.x == 0.5) && (f1.y == 2.5) && (f1.z == 1.5) && (f1.w == 4.1);
}

Float4.TestInplaceNormalize = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	f0.Normalize();
	return (1.0 == f0.Length());
}

Float4.TestNormalize = function()
{
	var f0 = Float4.FromValues(2.0, 3.0, 4.0, 5.0);
	var f1 = Float4.Normalize(f0);
	return (1.0 == f1.Length()) &&
	       (f0.x == 2.0) && (f0.y == 3.0) && (f0.z == 4.0) && (f0.w == 5.0);
}

Float4.RunTests = function()
{
	testRunner = new TestRunner("Float4 Tests");
	testRunner.Add("Default Constructor", Float4.TestDefaultConstructor);
	testRunner.Add("Create From Values", Float4.TestFromValues);
	testRunner.Add("Create From Float4", Float4.TestFromFloat4);
	testRunner.Add("Set Values", Float4.TestSet);
	testRunner.Add("Inplace Add", Float4.TestInplaceAdd);
	testRunner.Add("Add", Float4.TestAdd);
	testRunner.Add("Inplace Sub", Float4.TestInplaceSub);
	testRunner.Add("Sub", Float4.TestSub);
	testRunner.Add("Dot3", Float4.TestDot3);
	testRunner.Add("Length", Float4.TestLength);
	testRunner.Add("Length Squared", Float4.TestLengthSquared);
	testRunner.Add("Reciprocal", Float4.TestReciprocal);
	testRunner.Add("Inplace Mul", Float4.TestInplaceMul);
	testRunner.Add("Mul", Float4.TestMul);
	testRunner.Add("Abs", Float4.TestAbs);
	testRunner.Add("Inplace Cross3", Float4.TestInplaceCross3);
	testRunner.Add("Cross3", Float4.TestCross3);
	testRunner.Add("Inplace Lerp", Float4.TestInplaceLerp);
	testRunner.Add("Lerp", Float4.TestLerp);
	testRunner.Add("Inplace Max", Float4.TestInplaceMax);
	testRunner.Add("Max", Float4.TestMax);
	testRunner.Add("Inplace Min", Float4.TestInplaceMin);
	testRunner.Add("Min", Float4.TestMin);
	testRunner.Add("Inplace Normalize", Float4.TestInplaceNormalize);
	testRunner.Add("Normalize", Float4.TestNormalize);
	testRunner.Run();
}
